package com.laity.lock;

import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author: Laity
 * @Project: JavaLaity
 * @Package: com.laity.lock.SpinlockDemo
 * @Date: 2023年12月15日 17:44
 * @Description: 实现自旋锁
 */

public class SpinlockDemo {

    // int 0
    // boolean false
    // Thread null
    AtomicReference<Thread> atomicReference = new AtomicReference<>();

    // 创建锁
    public void myLock() {
        Thread thread = Thread.currentThread();

        // 如果我的线程是空，则把我的线程丢进去，设置当前线程为锁
        // 当前线程不为空，则等待
        System.out.println("当前线程：" + thread.getName() + "获取锁");
//        do {
//            // 自旋
//            System.out.println("当前线程：" + thread.getName() + "获取锁");
//        } while (!atomicReference.compareAndSet(null, thread));
        while (!atomicReference.compareAndSet(null, thread)){

        }
    }
    // 释放锁
    public void myUnlock() {
        Thread thread = Thread.currentThread();
        System.out.println("当前线程：" + thread.getName() + "释放锁");
        // 释放锁
        atomicReference.compareAndSet(thread, null);
    }


    public static void main(String[] args) throws InterruptedException {

        // 底层使用的是CAS自旋锁
        SpinlockDemo spinlockDemo = new SpinlockDemo();
        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                spinlockDemo.myLock();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                spinlockDemo.myUnlock();
            }, "t1").start();
        }
        Thread.sleep(3000);
        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                spinlockDemo.myLock();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                spinlockDemo.myUnlock();
            }, "t2").start();
        }
    }
}
